#include <iostream>
#include "ros/ros.h"
#include "msg/ImageTextMsg.h"
#include <sensor_msgs/CompressedImage.h>
#include <opencv2/opencv.hpp>
#include <cv_bridge/cv_bridge.h>
#include <image_transport/image_transport.h>
#include <curl/curl.h>
#include <nlohmann/json.hpp>
#include "yaml-cpp/yaml.h"
#include "std_msgs/String.h"



ros::Publisher custom_publisher;

static size_t WriteCallback(void *contents, size_t size, size_t nmemb, std::string *userp) {
    userp->append((char*)contents, size * nmemb);
    return size * nmemb;
}

nlohmann::json  post_request(const std::string& url, const std::string& post_fields) {
    CURL *curl;
    CURLcode res;
    std::string readBuffer;
    
    curl_global_init(CURL_GLOBAL_ALL);
    curl = curl_easy_init();
    using json = nlohmann::json;
    json jsonData;
    if(curl) {
        curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_fields.c_str());

        struct curl_slist *headers = NULL;
        headers = curl_slist_append(headers, "Content-Type: application/json");
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);

        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
	curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60L);
        res = curl_easy_perform(curl);
        if(res != CURLE_OK) {
            std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << std::endl;
        } else {
            std::cout << "Received Buffer: " << readBuffer << std::endl;
	    //using json = nlohmann::json;
	    jsonData = json::parse(readBuffer);
	    std::cout<<jsonData["generated_code"]<<std::endl;
	    //std::cout << "Received Buffer: " << readBuffer["generated_code"] << std::endl;
        }

        // Clean up
        curl_slist_free_all(headers);
        curl_easy_cleanup(curl);
	//return jsonData
    }
    
    //nlohmann::json empty_json_object;

    curl_global_cleanup();
    return jsonData;

}


void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
    std::string config_file_path = "/home/fengchao/catkin_ws/src/chaogege/config/config.yaml";
    std::string  url;
	try
    {
        YAML::Node config = YAML::LoadFile(config_file_path);

        // 获取参数值
        std::string  url = config["url"].as<std::string>();

        // 使用参数
        std::cout<<url.c_str()<<std::endl;
    }
    catch (const std::exception &e)
    {
        ROS_ERROR("Failed to read the configuration file: %s", e.what());
    }
    ROS_INFO("Received message: %s", msg->data.c_str());
    // std::string url = "http://localhost:5000/generate_code";
    std::string post_fields = R"({"model": "glm-4", "user_message": ")" +  std::string(msg->data.c_str()) + R"("})";
    std::cout<<"url: "<<url.c_str()<<"-------------"<<std::endl;
    std::cout<<post_fields<<"-------------"<<std::endl;
    post_request(url.c_str(), post_fields);
}


void imageTextCallback(const Parser::ImageTextMsg::ConstPtr& msg)
{
    std::string config_file_path = "/home/fengchao/catkin_ws/src/chaogege/config/config.yaml";
    std::string  url;
    try
    {
        YAML::Node config = YAML::LoadFile(config_file_path);

        // 获取参数值
        url = config["url"].as<std::string>();

        // 使用参数
        std::cout<<url.c_str()<<std::endl;
    }
    catch (const std::exception &e)
    {
        ROS_ERROR("Failed to read the configuration file: %s", e.what());
    }
    // 处理接收到的图像和文本消息
    cv_bridge::CvImagePtr cv_ptr;
    try
    {
        cv_ptr = cv_bridge::toCvCopy(msg->image, sensor_msgs::image_encodings::BGR8);
    }
    catch (cv_bridge::Exception& e)
    {
        ROS_ERROR("cv_bridge exception: %s", e.what());
        return;
    }
    
    std::string text = msg->text;
    
    // 在控制台输出图像和文本信息
    std::cout << "Received Image" << std::endl;
    std::cout << "Received Text: " << text << std::endl;
	
    std::string post_fields = R"({"model": "glm-4", "user_message": ")" +  std::string(text) + R"("})";
    std::cout<<post_fields<<"-------------"<<std::endl;
    std::cout<<url<<"-------------------------"<<std::endl;
    using json = nlohmann::json;
    cv::Mat image = cv_ptr->image;
    cv::imwrite("received_image.jpg", image);  // 保存图像文件
    ROS_INFO("Saved image to received_image.jpg");
    json json_data = post_request(url.c_str(), post_fields);

    //ros::init(0, nullptr,"Parser_node");
    //ros::NodeHandle nh;
    //ros::Publisher custom_publisher = nh.advertise<Parser::ImageTextMsg>("Parser_topic", 1);
    Parser::ImageTextMsg custom_msg;
    custom_msg.text = json_data["generated_code"];
    custom_msg.image = msg->image;

    custom_publisher.publish(custom_msg);
    //ros::spinOnce();


    
    //cv::Mat image = cv_ptr->image;
	
    //cv::imwrite("received_image.jpg", image);  // 保存图像文件
    //ROS_INFO("Saved image to received_image.jpg");

    
    cv::waitKey(1);
}

int main(int argc, char **argv)
{
    ros::init(argc, argv, "subscribe_image_and_text");
    ros::NodeHandle nh;
    custom_publisher = nh.advertise<Parser::ImageTextMsg>("Parser_topic", 1);
    ros::Subscriber sub = nh.subscribe("image_and_text_topic", 10, imageTextCallback);

    ros::spin();

    return 0;
}

